import { findClosestByPath, findInRange, getObjectsByPrototype, getRange } from 'game/utils';
import { Creep, StructureContainer, StructureSpawn } from 'game/prototypes';
import { ATTACK, CARRY, ERR_NOT_IN_RANGE, MOVE, RANGED_ATTACK, RESOURCE_ENERGY, TOUGH, WORK } from 'game/constants';
import { UnitManager } from './UnitManager';
import { searchPath } from 'game/path-finder';
import { CREEP_LEFT_STATUS_DIE, CREEP_LIFT_STATUS_LIVING, CreepUnit } from './SapwnHander';

// 单位管理
const MAX_WORK_NUM = 3;
// 多少战队单位为充足
const MANY_MELLY_NUM = 10;
// 战斗群
const BATTLE_GROUP = 7;
var RALLY_FLAG = true;
// 集结点
var RALLY_POINT;

export class CreepManager {

    /**
     * @type {UnitManager}
     */
    unitManager;

    /**
     * @type {StructureSpawn}
     */
    spawn;
    /**
     * @type {CreepUnit[]}
     */
    workCreeps = [];
    /**
     * @type {CreepUnit[]}
     */
    melleCreeps = [];
    // 单位body
    WORK_BODY = [MOVE, MOVE, MOVE, MOVE, CARRY, CARRY]
    MELEE_BODY = [MOVE, MOVE, ATTACK, RANGED_ATTACK, RANGED_ATTACK, RANGED_ATTACK];


    loop() {
        this.workCreepLoop();
        this.melleCreepLoop();
    }

    // 工作单位生命周期
    workCreepLoop() {
        // 剔除死亡单位
        this.workCreeps = this.clearCreeps(this.workCreeps);
        if (this.workCreeps.length == 0) {
            console.log("无任何工作单位.");
            return;
        }

        var creeps = this.workCreeps.map(creepUnit => creepUnit.creep);

        // 挖矿逻辑
        creeps.forEach(creep => {
            if (!creep.id) { return; }
            if (!creep.exists) { return; }
            var myUnit = this.unitManager.myUnit;
            if (creep.store.getUsedCapacity() == 0) {
                var container = getObjectsByPrototype(StructureContainer).filter(constant => constant.store[RESOURCE_ENERGY] > 0);
                var constant = creep.findClosestByPath(container);
                if (!constant['link']) {
                    constant['link'] = [];
                    constant['link'].push(creep);
                } else {
                    // console.log("资源有关联目标", constant)
                }

                if (constant) {
                    if (creep.withdraw(constant, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
                        creep.moveTo(constant);
                    }
                } else {
                    console.log("资源枯竭.");
                }
            } else {
                if (creep.transfer(myUnit.spawn, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
                    creep.moveTo(myUnit.spawn);
                }
            }
        });
    }

    // 战斗单位生命周期
    melleCreepLoop() {
        this.melleCreeps = this.clearCreeps(this.melleCreeps);
        if (this.melleCreeps.length == 0) {
            console.log("无任何战斗单位.");
            return;
        }
        var creeps = this.melleCreeps.map(creepUnit => creepUnit.creep);
        var rallyFlag = RALLY_FLAG;
        // 集结点

        creeps.forEach(creep => {
            if (!creep.id) { return; }
            if (!creep.exists) { return; }
            if (this.unitManager.enemyUnit.creeps.length > 0) {
                
                var targets = this.unitManager.enemyUnit.creeps;
                var nearTarget = creep.findClosestByPath(targets);
                var range = getRange(creep, nearTarget);
               
                if (this.melleCreeps.length < BATTLE_GROUP && rallyFlag) {
                    if(!RALLY_POINT) {
                        RALLY_POINT = searchPath(creep, nearTarget).path[5];
                    }
                    console.log("开始集合到：", RALLY_POINT)
                    creep.moveTo(RALLY_POINT);
                    return;
                } else if(RALLY_FLAG){
                    RALLY_FLAG = false;
                }

                if(range < 4) {
                    console.log("提前结束集结");
                    RALLY_FLAG = false;
                }
                
                if (range > 3) {                                              // 最近目标超出可攻击距离, 向最近单位移动
                    creep.moveTo(nearTarget);
                }
                else if (creep.attack(nearTarget) == ERR_NOT_IN_RANGE)        // 尝试近站
                {
                    var ret = searchPath(creep, nearTarget);
                    if (range <= 3 && ret.cost <= 5) {
                        creep.moveTo(nearTarget);
                    } else {
                        if (creep.rangedAttack(nearTarget) == ERR_NOT_IN_RANGE) // 远程攻击
                        {
                            creep.moveTo(nearTarget);
                        }
                    }
                }
            }
            // 再攻击基地
            else {
                var targetSpawn = this.unitManager.enemyUnit.spawn;
                if (creep.attack(targetSpawn) == ERR_NOT_IN_RANGE) {
                    creep.moveTo(targetSpawn);
                }
            }
        });
    }

    // 工作单位是否满员
    wordCreepIsFull() {
        return this.workCreeps.length >= MAX_WORK_NUM;
    }
    // 
    // melleCreepIsMany() {
    //     return this.melleCreeps.filter(creep => creep && creep.id && creep.exists).length >= MANY_MELLY_NUM;
    // }

    /**
     * @param {CreepUnit[]} creeps
     */
    clearCreeps(creeps) {
        return creeps.filter(creepUnit => creepUnit.getLiftStatus() != CREEP_LEFT_STATUS_DIE);
    }

}